﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Reflection;
using Exceptions.Custom;
using Microsoft.CSharp;

namespace Compiler.Entities
{
    /// <summary>
    /// Custom compiler Csharp 
    /// </summary>
    public static class Program
    {
        /// <summary>
        /// Return an object like the resultat of the operation
        /// </summary>
        public static object Execute(string program)
        {
            CSharpCodeProvider codeprovider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
            CompilerResults results =
                codeprovider.CompileAssemblyFromSource(new CompilerParameters(), program);
            if (results.Errors.Count != 0)
                throw new HpException("Error in CompileExecutable : " + results.Errors.ToString());
            Type mainType = results.CompiledAssembly.GetType("Calculator");
            MethodInfo mainMethod = mainType.GetMethod("Execute");
            object result = null;
            try
            {
                result = mainMethod.Invoke(null, null);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException.GetType() == typeof(DivideByZeroException))
                    throw new DivideByZeroException(string.Format("/Error: Infinite Result"));
            }
            return result;
        }
    }
}
